﻿using System;
using System.Data;

namespace mssql.t4
{
	public abstract class BaseDataColumn
	{
		protected BaseDataColumn(DataColumn column)
		{
			Column = column;
		}

		protected DataColumn Column { get; set; }
		public abstract string SqlType { get; }

		public static BaseDataColumn Factory(DataColumn col)
		{
			if (typeof(Guid).FullName == col.DataType.FullName)
			{
				return new GuidDataColumn(col);
			}
			else if (typeof(int).FullName == col.DataType.FullName)
			{
				return new IntDataColumn(col);
			}
			else if (typeof(string).FullName == col.DataType.FullName)
			{
				return new StringDataColumn(col);
			}
			else if (typeof(bool).FullName == col.DataType.FullName)
			{
				return new BooleanDataColumn(col);
			}
			else if (typeof(DateTime).FullName == col.DataType.FullName)
			{
				return new DateTimeDataColumn(col);
			}
			else if (typeof(long).FullName == col.DataType.FullName)
			{
				return new LongDataColumn(col);
			}
			else if (typeof(decimal).FullName == col.DataType.FullName)
			{
				return new DecimalDataColumn(col);
			}
			else if (typeof(byte[]).FullName == col.DataType.FullName)
			{
				return new BytesArrayDataColumn(col);
			}
			else if (typeof(byte).FullName == col.DataType.FullName)
			{
				return new ByteDataColumn(col);
			}
			else
			{
				throw new NotImplementedException("BaseDataColum::Factory for '" + col.DataType.Name + "' undefined");
			}
		}

		public string NullDescription { get { return (Column.AllowDBNull ? string.Empty : "NOT ") + "NULL"; } }

		public override string ToString()
		{
			return string.Format("	[{0}]	{1}	{2}", Column.ColumnName, SqlType, NullDescription);
		}
	}

	public class GuidDataColumn : BaseDataColumn
	{
		public GuidDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "UNIQUEIDENTIFIER"; } }
	}

	public class IntDataColumn : BaseDataColumn
	{
		public IntDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "INT"; } }
	}

	public class StringDataColumn : BaseDataColumn
	{
		public StringDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "NVARCHAR(MAX)"; } }
	}

	public class BooleanDataColumn : BaseDataColumn
	{
		public BooleanDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "BIT"; } }
	}

	public class DateTimeDataColumn : BaseDataColumn
	{
		public DateTimeDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "DATETIME2"; } }
	}

	public class LongDataColumn : BaseDataColumn
	{
		public LongDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "BIGINT"; } }
	}

	public class DecimalDataColumn : BaseDataColumn
	{
		public DecimalDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "DECIMAL(8,2)"; } }
	}

	public class BytesArrayDataColumn : BaseDataColumn
	{
		public BytesArrayDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "VARBINARY(MAX)"; } }
	}

	public class ByteDataColumn : BaseDataColumn
	{
		public ByteDataColumn(System.Data.DataColumn column) : base(column) { }

		public override string SqlType { get { return "TINYINT"; } }
	}
}